package mlz.atm;

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

//ATM系统 ->  操作数据 -> 完成业务逻辑
//ATM系统中 -> 账户 -> 集合ArrayList
public class ATM {
    //新建集合对象,用于存储账户信息
    private ArrayList<Account> accounts = new ArrayList<>();//(账户,账户)

    //新建控制台类
    private Scanner sc = new Scanner(System.in);

    //定义一个成员变量用于存储已经登录好的用户账号
    private Account loginAcc; //null

    //编写欢迎页面 -> 调用方法进入ATM系统
    public void start(){
        while (true) {
            System.out.println("===欢迎您进入到了ATM系统===");
            System.out.println("1、用户登录");
            System.out.println("2、用户开户");
            System.out.println("请选择：");
            int command = sc.nextInt();
            switch (command){
                case 1:
                    //用户登录
                    login();
                    break;
                case 2:
                    //用户开户
                    createAccount();
                    break;
                default:
                    System.out.println("您的输入有误~");
            }
        }
    }

    /* 用户登录 -> 记录当前的登录用户 -> 才会拥有当前用户的所有信息 */
    private void login(){
        //1.判断系统中是否存在账户对象,存在才能登陆,如果是不存在,则直接结束登陆操作
        if (accounts.size() == 0){
            System.out.println("当前系统中没有账户,请先开户再进行登录");
            return;
        }
        //2.系统中存在账户对象,可以完成进行登录操作
        while(true){
            System.out.println("请输入您的登录的卡号:");
            //用户输入的卡号
            String cardId = sc.next();//122233 -> 50653587
            //3.判断卡号是否存在
            Account acc = getAccountByCardId(cardId);
            if (acc == null){
                //说明这个卡号是不存在的
                System.out.println("您输入的卡号不存在~~");
            }else {
                while (true) {
                    //卡号存在了,就做密码的判断
                    System.out.println("请输入您的登录密码:");
                    String password = sc.next();
                    //4.判断密码是否正确
                    if (acc.getPassword().equals(password)){
                        //记录登录后的用户信息
                        loginAcc = acc;
                        //密码正确
                        System.out.println("恭喜你:" + acc.getUserName() + "成功登录,您的卡号为:" + acc.getCardId());
                        //TODO把展示界面的功能写成一个方法,写好后回来调用
                        showUserCommand();
                        return;//完成登录后,结束方法.
                    }else {
                        System.out.println("您输入的密码不正确,请重新输入");
                    }
                }
            }
        }
    }


    /* 展示登录后的操作界面的*/
    private void showUserCommand(){
        while (true) {
            System.out.println(loginAcc.getUserName() + "您可以选择如下功能进行账户的处理-----");
            System.out.println("1、查询账户");
            System.out.println("2、存款");
            System.out.println("3、取款");
            System.out.println("4、转账");
            System.out.println("5、修改密码");
            System.out.println("6、退出");
            System.out.println("7、注销当前用户");
            //用户进行选择功能
            int command = sc.nextInt();
            switch (command){
                case 1:
                    //查询账号
                    showLoginAccount();
                    break;
                case 2:
                    //存款
                    depositMoney();
                    break;
                case 3:
                    //取款
                    drawMoney();
                    break;
                case 4:
                    //转账
                    transferMoney();
                    break;
                case 5:
                    //修改密码
                    updatePassword();
                    break;
                case 6:
                    //退出
                    System.out.println(loginAcc.getUserName() + "您退出程序成功~");
                    return;
                case 7:
                    //注销
                    //true / false
                    //boolean b = deleteAccount();
                    if (deleteAccount()){
                        //真正销户了,回到欢迎页面
                        return;
                    }
                    break;
                default:
                    System.out.println("您当前选择的操作不存在,请重新输入~");
            }
        }
    }


    /* 销户操作 */
    private boolean deleteAccount() {
        //1.判断是否要销户
        System.out.println("请问您真的要进行销户操作码? y/n");
        String command = sc.next();
        switch (command){
            case "y":
                //确定要进行销户
                //2.判断用户的账户中是否有钱 -> loginAcc
                if (loginAcc.getMoney() == 0){
                    //就可以进行销户
                    accounts.remove(loginAcc);
                    return true;
                }else {
                    System.out.println("对不起,你的账号中有钱,不允许销户~");
                    return false;
                }
            default:
                System.out.println("您好,您的用户保留了");
                return false;

        }
    }


    /* 修改密码*/
    private void updatePassword() {
        while (true) {
            //1.提醒用户认证当前的密码
            System.out.println("请您输入当前的账号的密码: ");
            String password = sc.next();

            //2.认证当前密码是否正确
            if (loginAcc.getPassword().equals(password)){
                //3.真正开始进行修改密码
                System.out.println("请输入您的新密码:");
                String newPassword = sc.next();

                System.out.println("请您确认密码:");
                String okPassword = sc.next();

                //4.判断两次 密码是否一致
                if (okPassword.equals(newPassword)){
                    //可以真正进行修改密码
                    loginAcc.setPassword(password);
                    System.out.println("恭喜你,您的密码修改成功~~");
                    return;
                }else {
                    System.out.println("您输入的密码不一致~~~");
                }
            }else {
                System.out.println("您输入的密码不正确~~");
            }
        }
    }

    /* 转账功能 */
    private void transferMoney() {
        System.out.println("==用户转账==");
        //1.判断当前系统中是否存在其他账户
        if (accounts.size() < 2){
            System.out.println("当前系统中只有一个账户,无法为其他账户转账~~~");
            return;
        }
        //2.判断自己的账户中是否有钱 -> 没有钱 -> 没办法转账
        if (loginAcc.getMoney() == 0){
            System.out.println("您自己账户没有余额,无法转账");
            return;
        }

        //接下来做真正的转账业务
        System.out.println("请输入对方的卡号: ");
        String cardId = sc.next();

        //张三 -> 李四(cardId)转账

        //3.判断这个卡号是否正确
        Account acc = getAccountByCardId(cardId);
        if (acc == null){
            System.out.println("您输入的账户不存在~"); //id
        }else {
            //对方的账户是存在的,可以进行用户认证 -> 针对名字进行认证
            String name = "*" + acc.getUserName().substring(1); //*四 -> 李四四四
            System.out.println("请您输入[" +name+ "]的姓氏:");
            String preName = sc.next();

            //5.判断用户输入的这个姓氏是否正确
            if (acc.getUserName().startsWith(preName)){ //李四 ->
                while (true) {
                    //如果一致则表示认证通过,可以开始转账业务
                    System.out.println("请输入您的转账金额:");
                    double money = sc.nextDouble();
                    //6. 判断这个金额是否没有超过自己的余额
                    if (loginAcc.getMoney() >= money){
                        //7.给对方转钱
                        //更新自己的账户余额
                        loginAcc.setMoney(loginAcc.getMoney() - money);
                        //更新对象的账户余额
                        acc.setMoney(acc.getMoney() + money);
                        System.out.println("您的转账成功~");
                        return;//转账成功了,结束方法
                    }else {
                        System.out.println("您的余额不足,最多可以转账:" + loginAcc.getMoney());
                    }
                }
            }else {
                System.out.println("对不起,您的姓氏认证有问题~~~");
            }
        }
    }

    /* 取款功能 */
    private void drawMoney() {
        //1.判断账户余额是否达到了100块钱,如果不够100元,就不让用户取款
        if (loginAcc.getMoney() < 100){
            System.out.println("您的账户余额不足100元,不允许取款~~~");
            return;
        }
        while (true) {
            //2.让用户输入取款金额
            System.out.println("请输入您的取款金额:");
            double money = sc.nextDouble();
            //3.判断用户余额是否足够
            if (loginAcc.getMoney() >= money){
                //账户中的钱是足够的
                //4.判断当前取款金额是否超过了每次的限额
                if (money > loginAcc.getLimit()){
                    System.out.println("您当前取款的金额超过了每次的限额,每次的取款限额:" + loginAcc.getLimit());
                }else {
                    //符合限额的情况 -> 相当于取款操作完成
                    loginAcc.setMoney(loginAcc.getMoney() - money);
                    System.out.println("您取款:" + money + "成功取款后的额度:" + loginAcc.getLimit());
                    break;
                }
            }else {
                System.out.println("余额不足,您的账户金额为:" + loginAcc.getMoney());
            }
        }
    }


    /* 存款功能 */
    private void depositMoney() {
        System.out.println("==存款操作==");
        System.out.println("请输入您的存款金额:");
        //控制台操作 - 用户存款
        double money = sc.nextDouble();

        //更新当前登录的账户的金额  100 + money
        loginAcc.setMoney(loginAcc.getMoney() + money);
        System.out.println("恭喜你,您存款:" + money + "成功,存款后的余额为:" + loginAcc.getMoney());
    }


    /* 展示当前登录的账户信息*/
    private void showLoginAccount() {
        System.out.println("==当前您的账户信息如下:==");
        System.out.println("卡号:" + loginAcc.getCardId());
        System.out.println("户主:" + loginAcc.getUserName());
        System.out.println("性别:" + loginAcc.getSex());
        System.out.println("余额:" + loginAcc.getMoney());
        System.out.println("每次取款额度:" + loginAcc.getLimit());
    }


    /* 开户功能 */
    private void createAccount(){
        //1.创建一个账户对象,用户封装用户的数据信息
        Account acc = new Account();
        //2.需要用户输入自己的开户信息,赋值给账户对象
        //用户名,性别,密码,余额,限额,卡号
        System.out.println("---请输入是您的账户名称---");
        String name = sc.next();
        acc.setUserName(name);

        while (true) {
            System.out.println("---请输入是您的性别---");
            char sex = sc.next().charAt(0);
            //char c = sex.charAt(0);
            if (sex == '男' || sex == '女'){
                acc.setSex(sex);
                break;
            }else {
                System.out.println("您输入的性别有误,请重新输入~");
            }
        }

        while (true) {
            System.out.println("---请输入是您的账号密码---");
            String password = sc.next();
            System.out.println("---请确认您的正确密码---");
            String okPassword = sc.next();
            //判断两次输入的密码是否一致
            if (okPassword.equals(password)){
                acc.setPassword(okPassword);
                break;
            }else {
                System.out.println("您输入的两次密码不一致,请重新输入");
            }
        }

        //余额 -> 默认0.0 -> 成员变量默认初始值 -> 0.0

        System.out.println("请输入您的取现限额:");
        double limit = sc.nextDouble();
        acc.setLimit(limit);

        //做个提示 -> 提示账号信息已经存储完毕 -> 显示账号的户主
        //TODO完成生成卡号后 继续完成的功能
        String cardId = createCardId();
        acc.setCardId(cardId);
        System.out.println("恭喜你:" + acc.getUserName() + "开户成功,您的卡号:" + acc.getCardId());

        //3.把这个账户对象,存入到账户集合中
        accounts.add(acc);
    }

    /* 生成卡号 - */
    //根据卡号查询当前账号对象
    private Account getAccountByCardId(String cardId){
        //1.遍历全部的账号对象
        for (int i = 0; i < accounts.size(); i++) {
            //获取下标对应的元素
            Account acc = accounts.get(i);
            //判断这个账户对象的卡号是否是我们要找的卡号
            if (acc.getCardId().equals(cardId)){
                return acc;
            }
        }
        return null;//查无次账户,也就意味着这个卡号是不存在的
    }

    // 返回一个8位数字的卡号, 而且这个卡号是不能重复的
    private String createCardId(){
        //1.定义一个String类型的变量用于记录8位数字作为一个卡号
        String cardId = ""; //87
        //2.使用循环生成对应的数字 -> 一共8个 -> 不可重复
        Random r = new Random();
        for (int i = 0; i < 8; i++) {
            int data = r.nextInt(10);//有取值范围 -> [0,1) 0-9
            cardId += data;
        }
        //3.判断cardId中记住的卡号,和其他用户的卡号是否重复了,如果是没有,才乐意作为一个新生成的卡号返回
        Account acc = getAccountByCardId(cardId);
        if (acc == null){
            return cardId;
        }
        return null;
    }



}













